package com.zhuanzhuan.hero.user.mq.consumer;

import com.bj58.youpin.common.utils.json.JsonUtils;
import com.zhuanzhuan.hero.biz.common.entity.risk.control.msg.RiskControlResultMsg;
import com.zhuanzhuan.hero.biz.common.enums.RiskControlResultType;
import com.zhuanzhuan.hero.biz.common.enums.RiskControlScene;
import com.zhuanzhuan.hero.user.consts.NumConsts;
import com.zhuanzhuan.hero.user.helper.ZzLockHelper;
import com.zhuanzhuan.hero.user.service.HeroUserContactService;
import com.zhuanzhuan.hero.user.service.HeroUserReliableRecordService;
import com.zhuanzhuan.hero.user.service.IFraternityAuthService;
import com.zhuanzhuan.hero.user.service.IUserService;
import com.zhuanzhuan.hunter.mq.consumer.anno.HunterConsumer;
import com.zhuanzhuan.zzlock.lock.ZZEtcdLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * @ClassName RiskControlConsumer
 * @Description
 * @Author hanjunjun
 * @Date 2024/6/20 21:26
 */
@Slf4j
@Component
public class RiskControlConsumer {

    private final String LOCK_KEY_FORMAT = "handlerRiskControlResult_%s_%s_%s";

    @Resource
    private IUserService userService;

    @Resource
    private HeroUserContactService userContactService;

    @Resource
    private IFraternityAuthService fraternityAuthService;

    @Resource
    private HeroUserReliableRecordService reliableRecordService;

    @Resource
    private ZzLockHelper lockHelper;

    @HunterConsumer(topic = "hero_risk_control_result", group = "risk_control_result_user")
    public boolean handlerRiskControlResult(String msgId, RiskControlResultMsg body) {
        log.info("handlerRiskControlResult msgId={} body={}", msgId, JsonUtils.toJsonWithoutNull(body));
        int result = body.getResult();
        if (RiskControlResultType.NOT_PASS.getCode() != result) {
            log.info("结果不是不通过，不处理");
            return true;
        }

        int scene = body.getScene();
        Long entityId = body.getEntityId();
        //不同字段被风控会分成多个mq，每个mq的rejectedFields里面只有一个字段
        List<String> rejectedFields = body.getRejectedFields();

        //rejectedFields里面只有一个字段 使用scene,entity,rejectField 上锁
        String lockKey = String.format(LOCK_KEY_FORMAT, scene, entityId, rejectedFields.get(NumConsts.ZERO));
        try (ZZEtcdLock lock = lockHelper.getLock(lockKey)) {
            if (!lock.tryLock()) {
                log.info("handlerRiskControlResult获取锁失败");
                return true;
            }
            return this.doHandle(scene, entityId, rejectedFields);
        }
    }

    private boolean doHandle(int scene, Long entityId, List<String> rejectedFields) {
        if (RiskControlScene.USER_BASE_INFO.getCode() == scene) {
            log.info("用户基本信息风控失败");
            return userService.userBaseInfoRiskcontrolFail(entityId, rejectedFields);
        }
        if (RiskControlScene.USER_CONTACT.getCode() == scene) {
            log.info("用户联系方式风控失败");
            return userContactService.riskcontrolFail(entityId, rejectedFields);
        }
        if (RiskControlScene.PERSONAL_PROFILE.getCode() == scene) {
            log.info("用户个人简介风控失败");
            return userService.personIntroductionRiskcontrolFail(entityId, rejectedFields);
        }
        if (RiskControlScene.FELLOW_CERTIFICATE_LABEL.getCode() == scene) {
            log.info("同行认证标签风控失败");
            return fraternityAuthService.riskControlFail(entityId, rejectedFields);
        }
        if (RiskControlScene.USER_COVER.getCode() == scene) {
            log.info("用户背景图风控失败");
            return userService.backdropControlFail(entityId, rejectedFields);
        }
        if (RiskControlScene.RECYCLE_MERCHANT_SHARE.getCode() == scene) {
            log.info("用户端外信息风控失败");
            return userService.userOuterInfoRiskcontrolFail(entityId, rejectedFields);
        }
        if (RiskControlScene.UNRELIABLE_CERTIFICATE.getCode() == scene) {
            log.info("用户不靠谱认证风控失败");
            return reliableRecordService.unreliableAuthRiskcontrolFail(entityId, rejectedFields);
        } else {
            log.info("scene={}, 不处理", scene);
        }

        return true;
    }
}
